package com.apisix.service.service;

import com.apisix.service.entity.Service;
import com.apisix.service.repository.ServiceRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Component
public class ServiceEntityService {

    private final ServiceRepository serviceRepository;
    private final ApisixService apisixService;
    private final ObjectMapper objectMapper;

    @Autowired
    public ServiceEntityService(ServiceRepository serviceRepository, ApisixService apisixService, ObjectMapper objectMapper) {
        this.serviceRepository = serviceRepository;
        this.apisixService = apisixService;
        this.objectMapper = objectMapper;
    }

    public List<Service> getAllServices() {
        return serviceRepository.findAll();
    }

    public Optional<Service> getServiceById(Long id) {
        return serviceRepository.findById(id);
    }

    public Optional<Service> getServiceByServiceId(String serviceId) {
        return serviceRepository.findByServiceId(serviceId);
    }

    @Transactional
    public Service createService(Service service) throws JsonProcessingException {
        // 如果未提供服务ID，则生成一个UUID
        if (service.getServiceId() == null || service.getServiceId().isEmpty()) {
            service.setServiceId(UUID.randomUUID().toString());
        }
        
        // 保存到数据库
        Service savedService = serviceRepository.save(service);
        
        // 在APISIX中创建
        Map<String, Object> serviceData = convertToApisixFormat(savedService);
        apisixService.createService(serviceData);
        
        return savedService;
    }

    @Transactional
    public Optional<Service> updateService(Long id, Service serviceDetails) throws JsonProcessingException {
        return serviceRepository.findById(id)
                .map(existingService -> {
                    // 更新服务信息
                    existingService.setName(serviceDetails.getName());
                    existingService.setUpstreamId(serviceDetails.getUpstreamId());
                    existingService.setPlugins(serviceDetails.getPlugins());
                    existingService.setEnableWebsocket(serviceDetails.getEnableWebsocket());
                    existingService.setTimeout(serviceDetails.getTimeout());
                    existingService.setHosts(serviceDetails.getHosts());
                    existingService.setDescription(serviceDetails.getDescription());
                    
                    Service updatedService = serviceRepository.save(existingService);
                    
                    try {
                        // 在APISIX中更新
                        Map<String, Object> serviceData = convertToApisixFormat(updatedService);
                        apisixService.updateService(updatedService.getServiceId(), serviceData);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException("Failed to update service in APISIX", e);
                    }
                    
                    return updatedService;
                });
    }

    @Transactional
    public boolean deleteService(Long id) {
        return serviceRepository.findById(id)
                .map(service -> {
                    // 首先从APISIX中删除
                    apisixService.deleteService(service.getServiceId());
                    
                    // 然后从数据库中删除
                    serviceRepository.delete(service);
                    return true;
                })
                .orElse(false);
    }

    public boolean existsByServiceId(String serviceId) {
        return serviceRepository.existsByServiceId(serviceId);
    }
    
    @Transactional
    public void syncServicesFromApisix() {
        List<Map<String, Object>> apisixServices = apisixService.getServices();
        
        for (Map<String, Object> apisixService : apisixServices) {
            String serviceId = (String) apisixService.get("id");
            
            if (!serviceRepository.existsByServiceId(serviceId)) {
                Service service = new Service();
                service.setServiceId(serviceId);
                
                // 提取服务信息
                Map<String, Object> value = (Map<String, Object>) apisixService.get("value");
                
                if (value.containsKey("name")) {
                    service.setName((String) value.get("name"));
                }
                
                if (value.containsKey("upstream_id")) {
                    service.setUpstreamId((String) value.get("upstream_id"));
                }
                
                if (value.containsKey("plugins")) {
                    try {
                        service.setPlugins(objectMapper.writeValueAsString(value.get("plugins")));
                    } catch (JsonProcessingException e) {
                        // 忽略转换错误
                    }
                }
                
                if (value.containsKey("enable_websocket")) {
                    service.setEnableWebsocket((Boolean) value.get("enable_websocket"));
                }
                
                if (value.containsKey("timeout")) {
                    Map<String, Object> timeout = (Map<String, Object>) value.get("timeout");
                    service.setTimeout((Integer) timeout.get("connect"));
                }
                
                if (value.containsKey("hosts")) {
                    try {
                        List<String> hosts = (List<String>) value.get("hosts");
                        service.setHosts(objectMapper.writeValueAsString(hosts));
                    } catch (JsonProcessingException e) {
                        // 忽略转换错误
                    }
                }
                
                if (value.containsKey("desc")) {
                    service.setDescription((String) value.get("desc"));
                }
                
                serviceRepository.save(service);
            }
        }
    }
    
    private Map<String, Object> convertToApisixFormat(Service service) throws JsonProcessingException {
        Map<String, Object> serviceData = new HashMap<>();
        
        serviceData.put("id", service.getServiceId());
        
        if (service.getName() != null && !service.getName().isEmpty()) {
            serviceData.put("name", service.getName());
        }
        
        if (service.getUpstreamId() != null && !service.getUpstreamId().isEmpty()) {
            serviceData.put("upstream_id", service.getUpstreamId());
        }
        
        if (service.getPlugins() != null && !service.getPlugins().isEmpty()) {
            Map<String, Object> plugins = objectMapper.readValue(service.getPlugins(), Map.class);
            serviceData.put("plugins", plugins);
        }
        
        if (service.getEnableWebsocket() != null) {
            serviceData.put("enable_websocket", service.getEnableWebsocket());
        }
        
        if (service.getTimeout() != null) {
            Map<String, Object> timeout = new HashMap<>();
            timeout.put("connect", service.getTimeout());
            timeout.put("send", service.getTimeout());
            timeout.put("read", service.getTimeout());
            serviceData.put("timeout", timeout);
        }
        
        if (service.getHosts() != null && !service.getHosts().isEmpty()) {
            List<String> hosts = objectMapper.readValue(service.getHosts(), List.class);
            serviceData.put("hosts", hosts);
        }
        
        if (service.getDescription() != null && !service.getDescription().isEmpty()) {
            serviceData.put("desc", service.getDescription());
        }
        
        return serviceData;
    }
} 